/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package facebook;

import com.restfb.json.JsonException;
import com.restfb.json.JsonObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

/**
 *
 * This class implements some utility methods.
 * @author Antonio
 */

public class Utilities {
    
    
    /**
     * Returns the application secret.
     * @return the application secret as a string
     */
    public static String getClientSecret(){
        return "1d2f07af980d57075e62856424a7c1b4";
    }

    /**
     * 
     * @param signed_request The encoded request parameter received from Facebook
     * @return The decoded payload contained in the request
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static String decodePayload(String signed_request, HttpSession session) throws IOException, 
            NoSuchAlgorithmException, InvalidKeyException{
         
            String appSecret = getClientSecret();

            String [] split = signed_request.split("[.]");
            String encoded_sig = split[0];
            String payload = split[1];
            
            //calculating signature
            SecretKeySpec secret = new SecretKeySpec(appSecret.getBytes(),"HMACSHA256");
            Mac mac = Mac.getInstance("HMACSHA256");         
            mac.init(secret);         
            byte[] digest = mac.doFinal(payload.getBytes());         
            String expectedSignature =  new String(digest);
            
            encoded_sig = encoded_sig.replace("-", "+");
            payload = payload.replace("-", "+");
            encoded_sig = encoded_sig.replace("_", "/");
            payload = payload.replace("_", "/");
            
            String decodedSignature = new String(Base64.decodeBase64(encoded_sig));
            String decodedPayload = new String(Base64.decodeBase64(payload));            
            
            if(expectedSignature.equals(decodedSignature)) //verify signature
                return decodedPayload;
            else{
                System.err.println("Signature not matching!");
                return null; //Null pointer exception should be treated!
            }
    }

    /**
      * Sets a unique random state parameter into the current session
      * @param session The current session
      * @return void
      */
    public static void csrfProtection(HttpSession session) throws NoSuchAlgorithmException,
            UnsupportedEncodingException {
        
            String uuid = UUID.randomUUID().toString();
            session.setAttribute("state", DigestUtils.md5Hex(uuid));   
    }

    /**
     * Returns the base url of the web app.
     */  
    public static  String getBaseUrl(HttpServletRequest request) {
        String scheme = request.getScheme();             // http
        String serverName = request.getServerName();     // hostname.com
        int serverPort = request.getServerPort();        // 80
        String contextPath = request.getContextPath();   // /mywebapp

        // Reconstruct original requesting URL
        String url = scheme+"://"+serverName+":"+serverPort+contextPath;
        return url;
    }

    /**
      * Try to get a key contained in the json object. If the key doesn't exist
      * the JsonException is caught and null is returned.
      * @param j The json object from whom extract the key.
      * @param key The key that has to be extracted.
      * @return The extracted key or null if not founded.
      */
    public static String tryGetJsonKey(JsonObject j, String key) {
         try {
            return j.getString(key);
        }
        catch(JsonException e){
            return null;
        }
    }

    /**
     * This method is not necessary anymore, probably.
     * @param accessTokenPage
     * @return
     * @throws MalformedURLException
     * @throws IOException
     */
    public String getFBAccesToken(String accessTokenPage) throws MalformedURLException,
        IOException{
        URL url = new URL (accessTokenPage);
        int r;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InputStream is = url.openStream();
        while ((r = is.read()) != -1)
           baos.write(r);
        String access_token = new String(baos.toByteArray());
        return access_token.split("=")[1];
    }   
}
